home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / Drtf / DRichProcess.cpp < prev    next >
Text File  |  1996-07-05  |  10KB  |  494 lines

  1. // DRichProcess.cpp
  2. // d.g.gilbert
  3.  
  4.  
  5. #include "Dvibrant.h"
  6. #include "DFile.h"
  7. #include "DRichProcess.h"
  8. #include "DRichViewNu.h"
  9.  
  10. #define rtfmapInternal
  11. #include "rtfmaps.h"
  12. #undef rtfmapInternal
  13.  
  14.  
  15. // struct StyleRec
  16.  
  17. //static DParagraph     gDefParaFmt;
  18. static StyleRec         gDefaultStyle;
  19. static Nlm_Uint4         gLinkcolor;
  20.  
  21. static char        *kDefaultFontname   = "Courier"; //"Times";
  22. static char        *kDefaultFontfamily = "Modern"; //"Roman";    
  23.  
  24.  
  25. StyleRec::StyleRec()
  26. {
  27.     style = DRichStyle();  // DRichStyle constructor handles !?
  28.     fontname= kDefaultFontname;
  29.     fontfamily= kDefaultFontfamily;
  30.     fontsize= DRichprocess::kDefaultFontsize;
  31. }
  32.  
  33.     
  34.     
  35. DRichprocess::DRichprocess( DFile* itsFile, DRichView* itsDoc, Nlm_MonitorPtr progress) :
  36.     fClass(tokUnknown), fMajor(0), fMinor(0), fParam(0),
  37.     fDataFile( itsFile), fDataBuffer( NULL), fDataSize(0), 
  38.     fDoc(itsDoc), fProgress(progress), fParaCount(0),
  39.     fText(NULL), fTextSize(0), fLastTextSize(0), fTextMax(0),
  40.     fLastChar(0), fPushedChar(EOF), fOutMap(NULL),
  41.     fStyleStackSize(0), fTitle(NULL), fNewStyle(true),
  42.     fEndOfData(false)
  43.     fTextMax= 1024;
  44.     fText= (char*) MemNew(fTextMax+1);
  45.  
  46.     fStyleMax= 5;
  47.     fStyleCount= 0;
  48.     fStyleArray= (DRichStyle*) Nlm_MemNew( fStyleMax*sizeof(DRichStyle));
  49.     fStyleStackSize= 0;
  50.  
  51. #if 0
  52.     fStyleRec.style = DRichStyle();
  53.             // don't need this jazz, constructors handle it
  54.     //DRichStyle    aStyle(false);
  55.     //fStyleRec.style= aStyle;
  56.     //fStyleRec.fontname= kDefaultFontname;
  57.     //fStyleRec.fontfamily= kDefaultFontfamily;
  58.     //fStyleRec.fontsize= kDefaultFontsize;
  59. #endif
  60.     fOldStyleRec= fStyleRec;
  61.     gDefaultStyle= fStyleRec;
  62.     
  63.     (void) GetNlmFont();
  64.     
  65.     // !?? static constructors for DParagraph should do all these !?
  66.     // fParaFmt = DParagraph();
  67.     fParaFmt.deftabstop = kDefTabstop;
  68.     // !?? static constructors for DParagraph should do all these !?
  69.     fOldParaFmt= fParaFmt;
  70.     fDefParaFmt= fParaFmt;
  71.  
  72.         // not for text types ?? (RTF should be ok w/ this...)
  73.     if (fDataFile) {
  74.         ulong fileindex;
  75.         fDataFile->GetDataMark( fileindex);
  76.         fDataFile->Open("rb"); // !!!!! DAMN TEXT TRANSLATION (0d to 0a) WAS SCREWING US UP !!
  77.         fDataFile->SetDataMark( fileindex);
  78.         }
  79. }
  80.  
  81.     
  82. DRichprocess::~DRichprocess()
  83. {
  84.     Close();
  85.     //if (fDataFile) fDataFile->Close(); // caller may do this?
  86.     MemFree(fText);
  87.     MemFree(fStyleArray);
  88.     MemFree(fTitle);
  89.     
  90. }
  91.  
  92. void DRichprocess::SetBuffer( char* dataBuffer, ulong dataSize, Boolean endOfData)
  93. {
  94.     fDataSize= dataSize;
  95.     if (dataSize) fDataBuffer= dataBuffer;
  96.     else fDataBuffer= NULL; // prevent GetOneChar trying to read when no data !
  97.     fEndOfData= endOfData;
  98. }
  99.  
  100. void DRichprocess::Read()
  101. {
  102.     while (GetToken() != tokEOF) 
  103.         RouteToken();
  104.     Close();
  105. }
  106.  
  107. void DRichprocess::Close()
  108. {
  109.     if (fTextSize>0) {
  110.         PutLitCharWithStyle('\n');
  111.         NewParagraph(); /* push last text into doc */
  112.         }
  113.     if (fProgress && fDataFile) {
  114.         long fat= fDataFile->Tell();
  115.         if (fat>0) (void) Nlm_MonitorIntValue(fProgress, fat);
  116.         }
  117. }
  118.  
  119.  
  120. short DRichprocess::GetOneChar()
  121. {
  122.     short    c;
  123.  
  124.     if (fDataBuffer) {
  125.         c= (unsigned char) *fDataBuffer; // must be unsigned !!
  126.         if (fDataSize) {    // for counted data
  127.             fDataSize--;
  128.             fDataBuffer++;
  129.             if (!fDataSize) fDataBuffer= NULL; //  so EOF next time
  130.             }
  131.         else if (c) fDataBuffer++; // for null-term data
  132.         else if (!fEndOfData) c= tokBreakInData;
  133.         else c= EOF;
  134.         }
  135.     else if (fDataFile) 
  136.         c = fgetc( fDataFile->fFile);
  137.     else {
  138.         if (!fEndOfData) c= tokBreakInData;
  139.         else c= EOF;
  140.         }
  141.     return (c);
  142. }
  143.  
  144.  
  145. void DRichprocess::Pushback(char c) // private
  146. {
  147.     if (c != EOF) {
  148.         fPushedChar = c;
  149.         }
  150. }
  151.  
  152.  
  153. void DRichprocess::RouteToken()
  154. {
  155.     switch( fClass ) {
  156.         case tokUnknown:  
  157.             handleUnknownClass(); 
  158.             break;
  159.         case tokText: 
  160.             handleTextClass(); 
  161.             break;
  162.         case tokControl:  
  163.             handleControlClass(); 
  164.             break;
  165.         default:
  166.             //RTFPanic ("Unknown class %d: %s ", fClass, fTokenBuf);
  167.             break;
  168.         }    
  169. }
  170.  
  171. short DRichprocess::GetToken()
  172. {
  173.     do GetToken1(); 
  174.     while (fClass == tokDropchar);
  175.     return (fClass);
  176. }
  177.  
  178.  
  179. void DRichprocess::GetToken1() // private
  180. {
  181.     short    c;
  182.     
  183.         /* initialize token vars */
  184.     fClass = tokUnknown;
  185.     fParam = tokNoParam;
  186.  
  187.         /* get first token character, which may be a pushback from previous token */
  188.     if (fPushedChar != EOF) {
  189.         c = fPushedChar;
  190.         fPushedChar = EOF;
  191.         }
  192.     else 
  193.         c= GetOneChar();
  194.          
  195.     switch ( c ) {
  196.     
  197.         case EOF:
  198.             fClass = tokEOF;
  199.             fMajor = 0;
  200.             return;
  201.         case tokBreakInData:
  202.             fClass= tokEOF;
  203.             fMajor= tokBreakInData;
  204.             return;
  205.             
  206.         case '\r': //RETURN
  207.           if (fMinor == '\n') { // nettext /n/r data ...
  208.               fClass = tokDropchar;
  209.               fMajor = tokNull; 
  210.               fMinor = 0;  
  211.               return;
  212.             }
  213.            goto caseNewline;
  214.            
  215.         case '\n': //NEWLINE:
  216.           if (fMinor == '\r') { // msdos /r/n data ...
  217.               fClass = tokDropchar;
  218.               fMajor = tokNull; 
  219.               fMinor = 0;  
  220.               return;
  221.             }
  222.         caseNewline:
  223.             fClass = tokControl;
  224.             fMajor = tokNewline; //tokSpecialChar;
  225.             fMinor = c; //tokNewline;
  226.             return;
  227.              
  228.         default: 
  229.             fClass = tokText;
  230.             fMajor = c;
  231.             fMinor = c; // MapChar( c);
  232.             return; 
  233.             
  234.         }
  235. }
  236.  
  237.  
  238.  
  239. // static
  240. char* DRichprocess::gGenCharMap=  DRichprocess::ReadOutputMap("gen");
  241. char* DRichprocess::gSymCharMap=  DRichprocess::ReadOutputMap("sym");
  242.  
  243. char* DRichprocess::ReadOutputMap( char *file)
  244. {
  245. // from rtfmaps.h
  246. #ifdef WIN_MAC
  247. # define     genInMap  mac_gen_CharCode 
  248. # define     symInMap  mac_sym_CharCode 
  249. #else
  250. # define     genInMap  ansi_gen_CharCode 
  251. # define     symInMap  ansi_sym_CharCode 
  252. #endif
  253.     short *inMap, i, val;
  254.     char *outMap = (char*) MemNew( rtfSC_MaxChar*sizeof(char));
  255.     
  256.     if (*file == 's') inMap= symInMap;
  257.     else inMap= genInMap;
  258.  
  259.     for (i= 0; i<rtfSC_MaxChar; i++) outMap[i]= 0;
  260.     for (i= 255; i >= 0; i--) {
  261.         val= inMap[i];
  262.         if (val>=0 && val<rtfSC_MaxChar) outMap[val]= i;
  263.         }
  264.     return outMap;
  265. }
  266.  
  267.  
  268.  
  269. void DRichprocess::PutLitChar(short c)
  270. {
  271.     if (fTextSize >= fTextMax) {
  272.         fTextMax = fTextSize + 1024;
  273.         fText= (char*) MemMore( fText, fTextMax + 1);
  274.         }
  275.     fText[fTextSize++]= (char) c;
  276.     /* fText[fTextSize]= '\0'; */
  277. }
  278.  
  279. void DRichprocess::PutLitStr(char *s)
  280. {
  281.     long len = StrLen(s);
  282.     if (len + fTextSize >= fTextMax) {
  283.         fTextMax = fTextSize + len + 1024;
  284.         fText= (Nlm_CharPtr) MemMore( fText, fTextMax + 1);
  285.         }
  286.     Nlm_MemCopy( fText + fTextSize, s, len); /* +1 for nul */
  287.     fTextSize += len;
  288. }
  289.  
  290. void DRichprocess::PutLitCharWithStyle(short c)
  291. {
  292.     if (IsNewStyle()) StoreStyle(fOldStyleRec.style, FALSE);  
  293.     PutLitChar(c);
  294. }
  295.  
  296.  
  297.  
  298. void DRichprocess::PutStdChar( short stdCode)
  299. {
  300.     if (fOutMap) {
  301.         int och = fOutMap[stdCode];
  302.         if (och == rtfSC_nothing)    {  
  303.             char    buf[80];
  304.             sprintf(buf, "{{%s}}", RTFStdCharName(stdCode));
  305.             PutLitStr(buf);
  306.             }
  307.         else {
  308.             PutLitChar(och);
  309.             }
  310.         }
  311.     else {
  312.         PutLitChar(stdCode); 
  313.         }
  314. }
  315.  
  316.  
  317. void DRichprocess::PutStdCharWithStyle(short stdCode)
  318. {
  319.     if (IsNewStyle()) StoreStyle(fOldStyleRec.style, FALSE);  
  320.     PutStdChar(stdCode);
  321. }
  322.  
  323.  
  324. void DRichprocess::StoreStyle(DRichStyle& theStyle, Boolean force)
  325. {
  326.     if (force || fTextSize) {  
  327.         if (fStyleCount >= fStyleMax) {
  328.             fStyleMax  = fStyleCount + 10;
  329.             fStyleArray= (DRichStyle*) MemMore(fStyleArray, fStyleMax*sizeof(DRichStyle));
  330.             }
  331.     
  332.         theStyle.nextofs= fTextSize; //fLastTextSize;
  333.         //theStyle.textlen= fTextSize - fLastTextSize;
  334.         fLastTextSize= fTextSize;
  335.         if (!fFont) theStyle.font= GetNlmFont(); //x
  336.              
  337.         theStyle.last= FALSE; /* make sure... */
  338.         if (fStyleArray) fStyleArray[fStyleCount]= theStyle;
  339.         fStyleCount++; 
  340.          
  341.         //PutLitChar(chStyleTag);
  342.         }
  343.     fOldStyleRec= fStyleRec; /* gOldStyle= gStyle;  */
  344.     (void) GetNlmFont();          
  345.     NotNewStyle();
  346. }
  347.  
  348. void DRichprocess::StoreStyleObject(DStyleObject* sob, short width, short height)
  349. {
  350.     fStyleRec.style.ispict= true;
  351.     fStyleRec.style.pixwidth= width; 
  352.     fStyleRec.style.pixheight= height; 
  353.     fStyleRec.style.fObject= sob;
  354.     PutLitChar(' ');  
  355.     StoreStyle(fStyleRec.style, TRUE);
  356.     fStyleRec.style.fObject= NULL;
  357.     fStyleRec.style.pixwidth= 0; 
  358.     fStyleRec.style.pixheight= 0; 
  359.     fStyleRec.style.ispict= FALSE;
  360.     fStyleRec.style.ismap= FALSE;
  361.     fOldStyleRec= fStyleRec;
  362.     NewStyle();
  363.     //PutLitCharWithStyle(' ');
  364. }
  365.  
  366.  
  367. Boolean DRichprocess::IsNewStyle() 
  368. #if 1 //x
  369.     return fNewStyle; 
  370. #else
  371.     return TestNewStyle();
  372. #endif
  373. }
  374.  
  375. Boolean DRichprocess::TestNewStyle()
  376. {
  377.     fNewStyle = ( fOldStyleRec.fontname != fStyleRec.fontname 
  378.                     || fOldStyleRec.fontfamily != fStyleRec.fontfamily 
  379.                     || fOldStyleRec.fontsize != fStyleRec.fontsize 
  380.                     || fOldStyleRec.style.IsNotEqual( &fStyleRec.style)
  381.                     );
  382.     return fNewStyle;
  383. }
  384.  
  385.  
  386.  
  387. Nlm_FonT DRichprocess::GetNlmFont()
  388. {
  389. #if 1  //x
  390.         // GetFont is a time waster, cut down # of these calls !!
  391.     if (!fFont || IsNewStyle()) {
  392.         fFont= Nlm_GetFont( fStyleRec.fontname, fStyleRec.fontsize, 
  393.                     fStyleRec.style.bold, fStyleRec.style.italic, fStyleRec.style.underline != 0, 
  394.                     fStyleRec.fontfamily);
  395.         }
  396. #else
  397.         fFont= Nlm_GetFont( fStyleRec.fontname, fStyleRec.fontsize, 
  398.                     fStyleRec.style.bold, fStyleRec.style.italic, fStyleRec.style.underline != 0, 
  399.                     fStyleRec.fontfamily);
  400. #endif
  401.     fStyleRec.style.font= fFont;
  402.     fOldStyleRec= fStyleRec; 
  403.     NotNewStyle();
  404.     return fFont;
  405. }
  406.  
  407. void DRichprocess::PushStyle()
  408. {
  409.     if (fStyleStackSize<kMaxStyleStack) 
  410.         fStyleStack[fStyleStackSize++]= fStyleRec;
  411. }
  412.  
  413. void DRichprocess::PopStyle()
  414. {            
  415.     if (fStyleStackSize>0) 
  416.         fStyleRec= fStyleStack[--fStyleStackSize];
  417.     NewStyle();
  418. }
  419.  
  420.  
  421. void DRichprocess::DefaultParag()
  422. {
  423.     fParaFmt= fDefParaFmt;
  424. }
  425.  
  426. void DRichprocess::SetDefaultParag(DParagraph* theDefault)
  427. {
  428.     fDefParaFmt= *theDefault;
  429. }
  430.  
  431. void DRichprocess::DefaultStyle()
  432. {
  433.     fStyleRec= gDefaultStyle;
  434.     TestNewStyle();
  435. }
  436.  
  437.  
  438. void DRichprocess::NewParagraph()
  439. {
  440.     /* when new data forces use of new Dgg_ParData, 
  441.         append current text & para & col to growing doc */
  442. #if 1            
  443.     (void) GetNlmFont();  
  444.     StoreStyle( fStyleRec.style, TRUE);    /* gOldStyle */
  445.     //fTextSize--; /* unput last chStyleTag */
  446. #endif
  447.  
  448.     fStyleArray[fStyleCount-1].last= TRUE;
  449.     fText[fTextSize]= 0;
  450.     
  451.     fDoc->Append( fText, &fParaFmt, fStyleArray, fStyleCount);
  452.  
  453.     if (fProgress && fDataFile && (fParaCount % 10 == 0)) 
  454.         (void) Nlm_MonitorIntValue(fProgress, fDataFile->Tell());
  455.     fParaCount++;
  456.     fOldParaFmt= fParaFmt;
  457.     fParaFmt.numstops= fTextSize= fLastTextSize= fStyleCount= 0;
  458. }
  459.  
  460.  
  461.  
  462.  
  463.  
  464. void DRichprocess::handleUnknownClass()
  465. {
  466.     // nothing
  467. }
  468.  
  469. void DRichprocess::handleTextClass()
  470. {
  471.     if (IsNewStyle()) StoreStyle(fOldStyleRec.style, FALSE);  
  472.     PutLitChar(fMinor); 
  473.     fLastChar= fMajor;
  474. }
  475.  
  476. void DRichprocess::handleControlClass()
  477. {
  478.     switch (fMajor) {
  479.         
  480.         case tokNewline:
  481.             PutLitCharWithStyle ('\n');
  482.             NewParagraph();
  483.             break;
  484.  
  485.         default:
  486.             break;
  487.         }
  488.  
  489. }
  490.  
  491.  
  492.